package main

import "fmt"

func main() {
	//testSlice()
	//testFor()
	//mainArray()

	// ret1 := intSum2()
	// ret2 := intSum2(10)
	// ret3 := intSum2(10, 20)
	// ret4 := intSum2(10, 20, 30)
	// fmt.Println(ret1, ret2, ret3, ret4) //0 10 30 60
	//breakDemo1()

	// a := 10
	// modify1(a)
	// fmt.Println(a) // 10
	// modify2(&a)
	// fmt.Println(a) // 100
	testArr()
	testMap()
}

func NineNineMultiplicationTable() {
	fmt.Printf("九九乘法表")
	for i := 1; i < 10; i++ {
		for j := 1; j <= i; j++ {
			k := i * j
			fmt.Printf("%v*%v=%v  ", i, j, k)
		}
		fmt.Printf("\n")
	}
}

func testSlice() {
	var a []string              //声明一个字符串切片
	var b = []int{}             //声明一个整型切片并初始化
	var c = []bool{false, true} //声明一个布尔切片并初始化
	fmt.Println(a)              //[]
	fmt.Println(b)              //[]
	fmt.Println(c)              //[false true]
	fmt.Println(a == nil)       //true
	fmt.Println(b == nil)       //false
	fmt.Println(c == nil)       //false

	//数组a中选出1<=索引值<4的元素组成切片s，得到的切片长度=high-low，容量等于得到的切片的底层数组的容量。
	arr := [5]int{1, 2, 3, 4, 5}
	s := arr[1:3] // s := a[low:high]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
	//make([]T, size, cap)
	makeSlice := make([]int, 2, 10)
	fmt.Println(makeSlice)      //[0 0]
	fmt.Println(len(makeSlice)) //2
	fmt.Println(cap(makeSlice)) //10

	//追加元素
	var appArr []int
	appArr = append(s, 1)       // [1]
	appArr = append(s, 2, 3, 4) // [1 2 3 4]
	s2 := []int{5, 6, 7}
	finalArr := append(appArr, s2...) // [1 2 3 4 5 6 7]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", finalArr, len(finalArr), cap(finalArr))

	var mkArr = make([]string, 5, 10)
	for i := 0; i < 10; i++ {
		mkArr = append(mkArr, fmt.Sprintf("%v", i))
	}
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", mkArr, len(mkArr), cap(mkArr))
}

func testArr() {
	var arr [10]int      // 声明了一个int类型的数组
	arr[0] = 42          // 数组下标是从0开始的
	arr[1] = 13          // 赋值操作
	a := [3]int{1, 2, 3} // 声明了一个长度为3的int数组

	b := [10]int{1, 2, 3} // 声明了一个长度为10的int数组，其中前三个元素初始化为1、2、3，其它默认为0

	c := [...]int{4, 5, 6} // 可以省略长度而采用`...`的方式，Go会自动根据元素个数来计算长度
	fmt.Printf("%#v \r\n", a)
	fmt.Printf("%#v \r\n", b)
	fmt.Printf("%#v \r\n", c)
}

func testMap() {
	// 声明一个key是字符串，值为int的字典,这种方式的声明需要在使用之前使用make初始化
	var numbers map[string]int
	// 另一种map的声明方式
	numbers = make(map[string]int)
	numbers["one"] = 1  //赋值
	numbers["ten"] = 10 //赋值
	numbers["three"] = 3

	fmt.Println("第三个数字是: ", numbers["three"]) // 读取数据
	fmt.Println(" ", numbers)                 // 读取数据
	// 打印出来如:第三个数字是: 3

	// 初始化一个字典
	rating := map[string]float32{"C": 5, "Go": 4.5, "Python": 4.5, "C++": 2}
	// map有两个返回值，第二个返回值，如果不存在key，那么ok为false，如果存在ok为true
	csharpRating, ok := rating["C#"]
	if ok {
		fmt.Println("C# is in the map and its rating is ", csharpRating)
	} else {
		fmt.Println("We have no rating associated with C# in the map")
	}

	delete(rating, "C") // 删除key为C的元素

	m := make(map[string]string)
	m["Hello"] = "Bonjour"
	m1 := m
	m1["Hello"] = "Salut" // 现在m["hello"]的值已经是Salut了
}

func testFor() {
	// sum := 0
	// for index := 0; index < 10; index++ {
	// 	sum += index
	// 	print(index)
	// }
	// fmt.Println("sum is equal to ", sum)

	a := [...]string{"北京", "上海", "深圳"}
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", a, len(a), cap(a))
	for i := 0; i < len(a); i++ {
		fmt.Println(a[i])
	}

	// 方法2：for range遍历
	for index, value := range a {
		fmt.Println(index, value)
	}
	//二维数组
	doubleArr := [3][2]string{
		{"北京", "上海"},
		{"广州", "深圳"},
		{"成都", "重庆"},
	}
	for _, v1 := range doubleArr {
		for _, v2 := range v1 {
			fmt.Printf("%s\t", v2)
		}
		fmt.Println()
	}

}

func modifyArray(x [3]int) {
	x[0] = 100
}

func modifyArray2(x [3][2]int) {
	x[2][0] = 100
}

func mainArray() {
	a := [3]int{10, 20, 30}
	modifyArray(a) //在modify中修改的是a的副本x
	fmt.Println(a) //[10 20 30]
	b := [3][2]int{
		{1, 1},
		{1, 1},
		{1, 1},
	}
	modifyArray2(b) //在modify中修改的是b的副本x
	fmt.Println(b)  //[[1 1] [1 1] [1 1]]
}

func intSum2(x ...int) int {
	fmt.Println(x) //x是一个切片
	sum := 0
	for _, v := range x {
		//sum = sum + v
		sum += v
	}
	return sum
}

func breakDemo1() {
BREAKDEMO1:
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				break BREAKDEMO1
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	fmt.Println("...")
}

func modify1(x int) {
	x = 100
}

func modify2(x *int) {
	*x = 100
}
